#include "Common.h"
#include "SDLInput.h"

namespace GenBen {

static inline MouseButton sdlToGenbenMButton(Uint8 sdl_button)
{
	switch(sdl_button)
	{
	case SDL_BUTTON_LEFT:
		return MBUTTON_LEFT;
	case SDL_BUTTON_RIGHT:
		return MBUTTON_RIGHT;
	case SDL_BUTTON_MIDDLE:
		return MBUTTON_MIDDLE;	
	}
	return MBUTTON_INVALID;
}

SDLInput::SDLInput()
{
	memset(&keyboard[0], 0, sizeof(keyboard));
	memset(&keyboard_current[0], 0, sizeof(keyboard_current));
	memset(&keyboard_last[0], 0, sizeof(keyboard_last));
	memset(&mouse[0], 0, sizeof(mouse));
	memset(&mouse_current[0], 0, sizeof(mouse_current));
	memset(&mouse_last[0], 0, sizeof(mouse_last));

	mouse_pos = mouse_pos_old = VectorI(0, 0);
}

SDLInput::~SDLInput()
{
}

bool SDLInput::isKeyPressed(Key key)
{
	return keyboard[key];
}

bool SDLInput::isKeyUp(Key key)
{
	return (keyboard_last[key] && !keyboard[key]);
}

bool SDLInput::isKeyDown(Key key)
{
	return (!keyboard_last[key] && keyboard[key]);
}

VectorI SDLInput::getMousePos()
{
	return mouse_pos;
}

VectorI SDLInput::getMouseRelativePos()
{
	return VectorI(mouse_pos.x - mouse_pos_old.x, mouse_pos.y - mouse_pos_old.y);
}

int SDLInput::getRelativeWheel()
{
	// TODO
	return 0;
}

bool SDLInput::isMouseButtonPressed(MouseButton button)
{
	return mouse[button];
}

bool SDLInput::isMouseButtonUp(MouseButton button)
{
	return (mouse_last[button] && !mouse[button]);
}

bool SDLInput::isMouseButtonDown(MouseButton button)
{
	return (!mouse_last[button] && mouse[button]);
}

bool SDLInput::process(const SDL_Event& evt)
{
	uint key;
	switch(evt.type)
	{
	case SDL_KEYDOWN:
		key = evt.key.keysym.sym;
		if(evt.key.keysym.sym == SDLK_UP)
			key = KEY_UP;
		if(evt.key.keysym.sym == SDLK_DOWN)
			key = KEY_DOWN;	
		if(evt.key.keysym.sym == SDLK_LEFT)
			key = KEY_LEFT;
		if(evt.key.keysym.sym == SDLK_RIGHT)
			key = KEY_RIGHT;
		keyboard_current[key & 0xFF] = true;
		break;
	case SDL_KEYUP:
		key = evt.key.keysym.sym;
		if(evt.key.keysym.sym == SDLK_UP)
			key = KEY_UP;
		if(evt.key.keysym.sym == SDLK_DOWN)
			key = KEY_DOWN;	
		if(evt.key.keysym.sym == SDLK_LEFT)
			key = KEY_LEFT;
		if(evt.key.keysym.sym == SDLK_RIGHT)
			key = KEY_RIGHT;
		keyboard_current[key & 0xFF] = false;
		break;

	case SDL_MOUSEMOTION:
		mouse_pos.x = evt.motion.x;
		mouse_pos.y = evt.motion.y;
		break;

	case SDL_MOUSEBUTTONDOWN:
		mouse_current[sdlToGenbenMButton(evt.button.button)] = true;
		break;

	case SDL_MOUSEBUTTONUP:
		mouse_current[sdlToGenbenMButton(evt.button.button)] = false;
		break;
	
	default:
		return false;
	}
	return true;
}

void SDLInput::update()
{
	memcpy(mouse_last, mouse, sizeof(mouse));
	memcpy(mouse, mouse_current, sizeof(mouse));

	memcpy(keyboard_last, keyboard, sizeof(keyboard));
	memcpy(keyboard, keyboard_current, sizeof(keyboard));

	mouse_pos_old = mouse_pos;
}

}
